package ee.battleship.game;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.sql.SQLException;
import java.util.Scanner;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import ee.battleship.classes.Player;

@WebServlet("/UserLogin")
public class UserLogin extends HttpServlet {

	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession();
		DBConnection connection = new DBConnection();
		
		String storedState = (String) session.getAttribute("FBState");
		String offeredState = request.getParameter("state");
		
		if (storedState == null || offeredState == null || !storedState.equals(offeredState)) {
			throw new ServletException("Stored and offered state does not match");
		}
		
		String code = request.getParameter("code");
		String userAccessToken = getUserAccessToken(code);
		String userInfoJSON = getUserInfo(userAccessToken);
		if (userAccessToken != null) {
//			request.setAttribute("FBCode", code);
//			request.setAttribute("FBUserAccessToken", userAccessToken);
//			try {
//				request.setAttribute("FBUserInfoJSON", new JSONObject(userInfoJSON));
//			} catch (JSONException e1) {
//				// TODO Auto-generated catch block
//				e1.printStackTrace();
//			}
			
			try {
				JSONObject jsonObjectUserInfo = new JSONObject(userInfoJSON);
				String name = jsonObjectUserInfo.get("first_name").toString();
				Player player = connection.getPlayerByName(name);

				if(player == null) {
					player = connection.insertPlayer(name);
				}

				session.setAttribute("player", player);	
				request.getRequestDispatcher("lobby.jsp").forward(request, response);
			} catch (SQLException e) {
				e.printStackTrace();
			} catch (JSONException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		} else {
			RequestDispatcher requestDispatcher = request.getRequestDispatcher("index.jsp");
			request.setAttribute("loginError", "Empty username is not allowed");
			if (requestDispatcher != null) {
				requestDispatcher.forward(request, response);
			}
		}
	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		HttpSession session = request.getSession();
		DBConnection connection = new DBConnection();

		String username = request.getParameter("username");
		
		Player player = null;
		
		if (username == "" || username == null) {
			RequestDispatcher requestDispatcher = request.getRequestDispatcher("index.jsp");
			request.setAttribute("loginError", "Empty username is not allowed");
			if (requestDispatcher != null) {
				requestDispatcher.forward(request, response);
			}
		} else {
			try {
				player = connection.getPlayerByName(username);

				if(player == null) {
					player = connection.insertPlayer(username);
				}

				session.setAttribute("player", player);
				response.sendRedirect("lobby.jsp");
				
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

		try {
			connection.closeConnection();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private String getUserAccessToken(String code) throws IOException {
		// Küsi Facebookilt vastus
		String content = getStringFromUrl("https://graph.facebook.com/oauth/access_token" +
				"?client_id="     + FBConstants.APP_ID + 
				"&redirect_uri="  + FBConstants.REDIRECT_URL + 
				"&client_secret=" + FBConstants.APP_SECRET + 
				"&code="          + code);
		
		// nopi vastusest välja user token
		String[] pairs = content.split("\\&");
	    for (int i = 0; i < pairs.length; i++) {
		    String[] fields = pairs[i].split("=");
		    String name = URLDecoder.decode(fields[0], "UTF-8");
		    String value = URLDecoder.decode(fields[1], "UTF-8");
		    if (name.equals("access_token")) {
		    	return value;
		    }
	    }
	    
		return null;
	}
	
	private String getUserInfo(String userAccessToken) throws IOException {
		return getStringFromUrl("https://graph.facebook.com/me?access_token=" + userAccessToken);
	}
	
	private String getStringFromUrl(String urlString) throws IOException {
		URL url = new URL(urlString);

		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		try {
			conn.setRequestMethod("GET");
			conn.setDoOutput(true);
			conn.setReadTimeout(10000);
			conn.connect();
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					conn.getInputStream()));

			StringBuilder sb = new StringBuilder();

			String line;
			while ((line = reader.readLine()) != null) {
				sb.append(line + "\n");
			}

			return sb.toString();
		} finally {
			conn.disconnect();
		}
	}
		
}
